<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 14 Tips &amp; Tricks | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.20 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 14 Tips &amp; Tricks | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 14 Tips &amp; Tricks | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-09-04" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="a-complete-integration.html"/>
<link rel="next" href="custom-outputs.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/accessible-code-block/empty-anchor.js"></script>
<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>
<script src="libs/viz/viz.js"></script>
<link href="libs/DiagrammeR-styles/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding/grViz.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="overview.html"><a href="overview.html"><i class="fa fa-check"></i><b>1</b> Overview</a>
<ul>
<li class="chapter" data-level="1.1" data-path="overview.html"><a href="overview.html#rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="overview.html"><a href="overview.html#methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a>
<ul>
<li class="chapter" data-level="1.2.1" data-path="overview.html"><a href="overview.html#v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="overview.html"><a href="overview.html#htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
<li class="chapter" data-level="1.2.4" data-path="overview.html"><a href="overview.html#bubble"><i class="fa fa-check"></i><b>1.2.4</b> bubble</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="overview.html"><a href="overview.html#methods-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a>
<ul>
<li class="chapter" data-level="1.3.1" data-path="overview.html"><a href="overview.html#reactr"><i class="fa fa-check"></i><b>1.3.1</b> reactR</a></li>
<li class="chapter" data-level="1.3.2" data-path="overview.html"><a href="overview.html#r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a>
<ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#r-package-development"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a>
<ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#creating-a-package"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#build-load-and-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#json"><i class="fa fa-check"></i><b>2.2</b> JSON</a>
<ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#tabular-data"><i class="fa fa-check"></i><b>2.2.2</b> Tabular data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a>
<ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#developer-tools"><i class="fa fa-check"></i><b>2.3.1</b> Developer tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#variable-declaration-and-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable declaration and scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#document-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document object model</a></li>
</ul></li>
<li class="chapter" data-level="2.4" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>2.4</b> Shiny</a>
<ul>
<li class="chapter" data-level="2.4.1" data-path="prerequisites.html"><a href="prerequisites.html#htmltools"><i class="fa fa-check"></i><b>2.4.1</b> Htmltools</a></li>
<li class="chapter" data-level="2.4.2" data-path="prerequisites.html"><a href="prerequisites.html#static-files"><i class="fa fa-check"></i><b>2.4.2</b> Static files</a></li>
<li class="chapter" data-level="2.4.3" data-path="prerequisites.html"><a href="prerequisites.html#dependencies-pros-and-cons"><i class="fa fa-check"></i><b>2.4.3</b> Dependencies Pros and Cons</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html"><i class="fa fa-check"></i><b>3</b> Introduction to Widgets</a>
<ul>
<li class="chapter" data-level="3.1" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#plotly-package"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#dt-package"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html"><i class="fa fa-check"></i><b>4</b> Basics of Building Widgets</a>
<ul>
<li class="chapter" data-level="4.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#candidate-libraries"><i class="fa fa-check"></i><b>4.1</b> Candidate Libraries</a>
<ul>
<li class="chapter" data-level="4.1.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#plotly.js"><i class="fa fa-check"></i><b>4.1.1</b> Plotly.js</a></li>
<li class="chapter" data-level="4.1.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#highchart.js"><i class="fa fa-check"></i><b>4.1.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.1.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#chart.js"><i class="fa fa-check"></i><b>4.1.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>4.2</b> How it works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="your-first-widget.html"><a href="your-first-widget.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a>
<ul>
<li class="chapter" data-level="5.1" data-path="your-first-widget.html"><a href="your-first-widget.html#the-htmlwidgets-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Htmlwidgets Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="your-first-widget.html"><a href="your-first-widget.html#the-html-output"><i class="fa fa-check"></i><b>5.2</b> The HTML Output</a></li>
<li class="chapter" data-level="5.3" data-path="your-first-widget.html"><a href="your-first-widget.html#htmlwidgets-javascript-files"><i class="fa fa-check"></i><b>5.3</b> Htmlwidgets JavaScript Files</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a>
<ul>
<li class="chapter" data-level="6.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#peity.js-dependencies"><i class="fa fa-check"></i><b>6.1</b> Peity.js Dependencies</a></li>
<li class="chapter" data-level="6.2" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#peity.js-implementation"><i class="fa fa-check"></i><b>6.2</b> Peity.js Implementation</a></li>
<li class="chapter" data-level="6.3" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#peity.js-html-element"><i class="fa fa-check"></i><b>6.3</b> Peity.js HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="the-full-monty.html"><a href="the-full-monty.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a>
<ul>
<li class="chapter" data-level="7.1" data-path="the-full-monty.html"><a href="the-full-monty.html#gio.js-dependencies"><i class="fa fa-check"></i><b>7.1</b> Gio.js Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="the-full-monty.html"><a href="the-full-monty.html#gio.js-javascript"><i class="fa fa-check"></i><b>7.2</b> Gio.js JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="the-full-monty.html"><a href="the-full-monty.html#transforming-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a>
<ul>
<li class="chapter" data-level="7.4.1" data-path="the-full-monty.html"><a href="the-full-monty.html#using-javascript"><i class="fa fa-check"></i><b>7.4.1</b> Using JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="the-full-monty.html"><a href="the-full-monty.html#using-r"><i class="fa fa-check"></i><b>7.4.2</b> Using R</a></li>
<li class="chapter" data-level="7.4.3" data-path="the-full-monty.html"><a href="the-full-monty.html#pros-cons"><i class="fa fa-check"></i><b>7.4.3</b> Pros &amp; Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="the-full-monty.html"><a href="the-full-monty.html#on-print-method"><i class="fa fa-check"></i><b>7.5</b> On Print Method</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="advanced-topics.html"><a href="advanced-topics.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a>
<ul>
<li class="chapter" data-level="8.1" data-path="advanced-topics.html"><a href="advanced-topics.html#shared-variables"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a>
<ul>
<li class="chapter" data-level="8.1.1" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="advanced-topics.html"><a href="advanced-topics.html#resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="advanced-topics.html"><a href="advanced-topics.html#pre-render-hooks-security"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks &amp; Security</a></li>
<li class="chapter" data-level="8.4" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="advanced-topics.html"><a href="advanced-topics.html#prepend-append-content"><i class="fa fa-check"></i><b>8.5</b> Prepend &amp; Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="advanced-topics.html"><a href="advanced-topics.html#dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="advanced-topics.html"><a href="advanced-topics.html#compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="advanced-topics.html"><a href="advanced-topics.html#unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="linking-widgets.html"><a href="linking-widgets.html"><i class="fa fa-check"></i><b>9</b> Linking Widgets</a>
<ul>
<li class="chapter" data-level="9.1" data-path="linking-widgets.html"><a href="linking-widgets.html#crosstalk-examples"><i class="fa fa-check"></i><b>9.1</b> Crosstalk examples</a></li>
<li class="chapter" data-level="9.2" data-path="linking-widgets.html"><a href="linking-widgets.html#crosstalk-requirements"><i class="fa fa-check"></i><b>9.2</b> Crosstalk requirements</a></li>
<li class="chapter" data-level="9.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>9.3</b> How it works</a></li>
<li class="chapter" data-level="9.4" data-path="linking-widgets.html"><a href="linking-widgets.html#crosstalk-with-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with gio</a></li>
<li class="chapter" data-level="9.5" data-path="linking-widgets.html"><a href="linking-widgets.html#adapt-the-r-code"><i class="fa fa-check"></i><b>9.5</b> Adapt the R code</a></li>
<li class="chapter" data-level="9.6" data-path="linking-widgets.html"><a href="linking-widgets.html#change-the-javascript-code"><i class="fa fa-check"></i><b>9.6</b> Change the JavaScript code</a>
<ul>
<li class="chapter" data-level="9.6.1" data-path="linking-widgets.html"><a href="linking-widgets.html#send-selected-keys"><i class="fa fa-check"></i><b>9.6.1</b> Send selected keys</a></li>
<li class="chapter" data-level="9.6.2" data-path="linking-widgets.html"><a href="linking-widgets.html#set-selected-keys"><i class="fa fa-check"></i><b>9.6.2</b> Set selected keys</a></li>
<li class="chapter" data-level="9.6.3" data-path="linking-widgets.html"><a href="linking-widgets.html#recap-javascript-code"><i class="fa fa-check"></i><b>9.6.3</b> Recap JavaScript code</a></li>
</ul></li>
<li class="chapter" data-level="9.7" data-path="linking-widgets.html"><a href="linking-widgets.html#using-crosstalk-with-gio"><i class="fa fa-check"></i><b>9.7</b> Using crosstalk with gio</a></li>
</ul></li>
<li class="chapter" data-level="10" data-path="final-revisions.html"><a href="final-revisions.html"><i class="fa fa-check"></i><b>10</b> Final Revisions</a>
<ul>
<li class="chapter" data-level="10.1" data-path="final-revisions.html"><a href="final-revisions.html#htmlwidgets-data"><i class="fa fa-check"></i><b>10.1</b> Htmlwidgets &amp; Data</a></li>
<li class="chapter" data-level="10.2" data-path="final-revisions.html"><a href="final-revisions.html#plethora-of-options"><i class="fa fa-check"></i><b>10.2</b> Plethora of Options</a></li>
<li class="chapter" data-level="10.3" data-path="final-revisions.html"><a href="final-revisions.html#interface-design"><i class="fa fa-check"></i><b>10.3</b> Interface Design</a></li>
</ul></li>
<li class="chapter" data-level="11" data-path="excercise-ploty.html"><a href="excercise-ploty.html"><i class="fa fa-check"></i><b>11</b> Excercise - Ploty</a>
<ul>
<li class="chapter" data-level="11.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#discover-plotly"><i class="fa fa-check"></i><b>11.1</b> Discover Plotly</a></li>
<li class="chapter" data-level="11.2" data-path="excercise-ploty.html"><a href="excercise-ploty.html#basics-of-plotly"><i class="fa fa-check"></i><b>11.2</b> Basics of Plotly</a></li>
<li class="chapter" data-level="11.3" data-path="excercise-ploty.html"><a href="excercise-ploty.html#plotly.js-to-r"><i class="fa fa-check"></i><b>11.3</b> Plotly.js to R</a></li>
<li class="chapter" data-level="11.4" data-path="excercise-ploty.html"><a href="excercise-ploty.html#r-to-plotly.js"><i class="fa fa-check"></i><b>11.4</b> R to Plotly.js</a></li>
<li class="chapter" data-level="11.5" data-path="excercise-ploty.html"><a href="excercise-ploty.html#size-resize-plotly.js"><i class="fa fa-check"></i><b>11.5</b> Size &amp; Resize Plotly.js</a></li>
<li class="chapter" data-level="11.6" data-path="excercise-ploty.html"><a href="excercise-ploty.html#performance-security-with-plotly.js"><i class="fa fa-check"></i><b>11.6</b> Performance &amp; Security with Plotly.js</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="12" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html"><i class="fa fa-check"></i><b>12</b> Introduction to Shiny</a>
<ul>
<li class="chapter" data-level="12.1" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#websocket-shiny"><i class="fa fa-check"></i><b>12.1</b> Websocket &amp; Shiny</a></li>
<li class="chapter" data-level="12.2" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-an-example"><i class="fa fa-check"></i><b>12.2</b> Alerts, An Example</a></li>
<li class="chapter" data-level="12.3" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-r-to-js"><i class="fa fa-check"></i><b>12.3</b> From R to JavaScript</a></li>
<li class="chapter" data-level="12.4" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-js-to-r"><i class="fa fa-check"></i><b>12.4</b> From JavaScript to R</a></li>
<li class="chapter" data-level="12.5" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-deserialise"><i class="fa fa-check"></i><b>12.5</b> Deserialise</a></li>
</ul></li>
<li class="chapter" data-level="13" data-path="a-complete-integration.html"><a href="a-complete-integration.html"><i class="fa fa-check"></i><b>13</b> A Complete Integration</a>
<ul>
<li class="chapter" data-level="13.1" data-path="a-complete-integration.html"><a href="a-complete-integration.html#serialisation"><i class="fa fa-check"></i><b>13.1</b> Serialisation</a></li>
<li class="chapter" data-level="13.2" data-path="a-complete-integration.html"><a href="a-complete-integration.html#events-callbacks"><i class="fa fa-check"></i><b>13.2</b> Events &amp; Callbacks</a></li>
<li class="chapter" data-level="13.3" data-path="a-complete-integration.html"><a href="a-complete-integration.html#as-a-package"><i class="fa fa-check"></i><b>13.3</b> As a Package</a>
<ul>
<li class="chapter" data-level="13.3.1" data-path="advanced-topics.html"><a href="advanced-topics.html#dependencies"><i class="fa fa-check"></i><b>13.3.1</b> Dependencies</a></li>
<li class="chapter" data-level="13.3.2" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>13.3.2</b> R Code</a></li>
<li class="chapter" data-level="13.3.3" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>13.3.3</b> JavaScript Code</a></li>
<li class="chapter" data-level="13.3.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>13.3.4</b> Input Handler</a></li>
<li class="chapter" data-level="13.3.5" data-path="a-complete-integration.html"><a href="a-complete-integration.html#wrapping-up"><i class="fa fa-check"></i><b>13.3.5</b> Wrapping up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="14" data-path="tips-tricks.html"><a href="tips-tricks.html"><i class="fa fa-check"></i><b>14</b> Tips &amp; Tricks</a>
<ul>
<li class="chapter" data-level="14.1" data-path="tips-tricks.html"><a href="tips-tricks.html#shiny-events"><i class="fa fa-check"></i><b>14.1</b> Shiny Events</a></li>
<li class="chapter" data-level="14.2" data-path="tips-tricks.html"><a href="tips-tricks.html#table-buttons"><i class="fa fa-check"></i><b>14.2</b> Table Buttons</a></li>
<li class="chapter" data-level="14.3" data-path="tips-tricks.html"><a href="tips-tricks.html#jquery---toggle"><i class="fa fa-check"></i><b>14.3</b> jQuery - Toggle</a></li>
</ul></li>
<li class="chapter" data-level="15" data-path="custom-outputs.html"><a href="custom-outputs.html"><i class="fa fa-check"></i><b>15</b> Custom Outputs</a>
<ul>
<li class="chapter" data-level="15.1" data-path="custom-outputs.html"><a href="custom-outputs.html#custom-outputs-inner-workings"><i class="fa fa-check"></i><b>15.1</b> Custom Outputs Inner-workings</a></li>
<li class="chapter" data-level="15.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup-custom-output"><i class="fa fa-check"></i><b>15.2</b> Setup Custom Output</a></li>
<li class="chapter" data-level="15.3" data-path="custom-outputs.html"><a href="custom-outputs.html#output-r-function"><i class="fa fa-check"></i><b>15.3</b> Output R Function</a></li>
<li class="chapter" data-level="15.4" data-path="custom-outputs.html"><a href="custom-outputs.html#generate-output-html"><i class="fa fa-check"></i><b>15.4</b> Generate Output HTML</a></li>
<li class="chapter" data-level="15.5" data-path="custom-outputs.html"><a href="custom-outputs.html#output-renderer"><i class="fa fa-check"></i><b>15.5</b> Output Renderer</a></li>
<li class="chapter" data-level="15.6" data-path="custom-outputs.html"><a href="custom-outputs.html#javascript-output-binding"><i class="fa fa-check"></i><b>15.6</b> JavaScript Output Binding</a>
<ul>
<li class="chapter" data-level="15.6.1" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-title"><i class="fa fa-check"></i><b>15.6.1</b> Boxxy title</a></li>
<li class="chapter" data-level="15.6.2" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-value"><i class="fa fa-check"></i><b>15.6.2</b> Boxxy value</a></li>
<li class="chapter" data-level="15.6.3" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-background-color"><i class="fa fa-check"></i><b>15.6.3</b> Boxxy Background Color</a></li>
<li class="chapter" data-level="15.6.4" data-path="custom-outputs.html"><a href="custom-outputs.html#register-the-output-binding"><i class="fa fa-check"></i><b>15.6.4</b> Register the Output Binding</a></li>
</ul></li>
<li class="chapter" data-level="15.7" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-usage"><i class="fa fa-check"></i><b>15.7</b> Boxxy Usage</a></li>
<li class="chapter" data-level="15.8" data-path="custom-outputs.html"><a href="custom-outputs.html#injecting-dependencies"><i class="fa fa-check"></i><b>15.8</b> Injecting Dependencies</a></li>
<li class="chapter" data-level="15.9" data-path="custom-outputs.html"><a href="custom-outputs.html#preprocessing-custom-outputs"><i class="fa fa-check"></i><b>15.9</b> Preprocessing Custom Outputs</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="custom-inputs.html"><a href="custom-inputs.html"><i class="fa fa-check"></i><b>16</b> Custom Inputs</a>
<ul>
<li class="chapter" data-level="16.1" data-path="custom-inputs.html"><a href="custom-inputs.html#setup-custom-input"><i class="fa fa-check"></i><b>16.1</b> Setup Custom Input</a></li>
<li class="chapter" data-level="16.2" data-path="custom-inputs.html"><a href="custom-inputs.html#switch-input-html-style"><i class="fa fa-check"></i><b>16.2</b> Switch Input HTML &amp; Style</a></li>
<li class="chapter" data-level="16.3" data-path="custom-inputs.html"><a href="custom-inputs.html#generate-input-html"><i class="fa fa-check"></i><b>16.3</b> Generate Input HTML</a></li>
<li class="chapter" data-level="16.4" data-path="custom-inputs.html"><a href="custom-inputs.html#javascript-input-binding"><i class="fa fa-check"></i><b>16.4</b> JavaScript Input Binding</a>
<ul>
<li class="chapter" data-level="16.4.1" data-path="custom-inputs.html"><a href="custom-inputs.html#find-inputs"><i class="fa fa-check"></i><b>16.4.1</b> Find Inputs</a></li>
<li class="chapter" data-level="16.4.2" data-path="custom-inputs.html"><a href="custom-inputs.html#get-input-id"><i class="fa fa-check"></i><b>16.4.2</b> Get Input Id</a></li>
<li class="chapter" data-level="16.4.3" data-path="custom-inputs.html"><a href="custom-inputs.html#get-input-value"><i class="fa fa-check"></i><b>16.4.3</b> Get Input Value</a></li>
<li class="chapter" data-level="16.4.4" data-path="custom-inputs.html"><a href="custom-inputs.html#set-input-value"><i class="fa fa-check"></i><b>16.4.4</b> Set Input Value</a></li>
<li class="chapter" data-level="16.4.5" data-path="custom-inputs.html"><a href="custom-inputs.html#receive-input-messages"><i class="fa fa-check"></i><b>16.4.5</b> Receive Input Messages</a></li>
<li class="chapter" data-level="16.4.6" data-path="custom-inputs.html"><a href="custom-inputs.html#subscribe-unsubscribe-inputs"><i class="fa fa-check"></i><b>16.4.6</b> Subscribe &amp; Unsubscribe Inputs</a></li>
<li class="chapter" data-level="16.4.7" data-path="custom-inputs.html"><a href="custom-inputs.html#input-rate-policy"><i class="fa fa-check"></i><b>16.4.7</b> Input Rate Policy</a></li>
<li class="chapter" data-level="16.4.8" data-path="custom-inputs.html"><a href="custom-inputs.html#registering-the-input"><i class="fa fa-check"></i><b>16.4.8</b> Registering the Input</a></li>
</ul></li>
<li class="chapter" data-level="16.5" data-path="custom-inputs.html"><a href="custom-inputs.html#update-input"><i class="fa fa-check"></i><b>16.5</b> Update Input</a></li>
<li class="chapter" data-level="16.6" data-path="custom-inputs.html"><a href="custom-inputs.html#exercise"><i class="fa fa-check"></i><b>16.6</b> Exercise</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="cookies.html"><a href="cookies.html"><i class="fa fa-check"></i><b>17</b> Cookies</a>
<ul>
<li class="chapter" data-level="17.1" data-path="cookies.html"><a href="cookies.html#discover-js-cookie"><i class="fa fa-check"></i><b>17.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="17.2" data-path="cookies.html"><a href="cookies.html#setup-cookies-project"><i class="fa fa-check"></i><b>17.2</b> Setup Cookies Project</a></li>
<li class="chapter" data-level="17.3" data-path="cookies.html"><a href="cookies.html#javascript-cookies"><i class="fa fa-check"></i><b>17.3</b> JavaScript Cookies</a></li>
<li class="chapter" data-level="17.4" data-path="cookies.html"><a href="cookies.html#r-code-for-cookies"><i class="fa fa-check"></i><b>17.4</b> R Code for Cookies</a></li>
</ul></li>
<li class="chapter" data-level="18" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html"><i class="fa fa-check"></i><b>18</b> Widgets with Shiny</a>
<ul>
<li class="chapter" data-level="18.1" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#widgets-to-r"><i class="fa fa-check"></i><b>18.1</b> Widgets to R</a></li>
<li class="chapter" data-level="18.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#input-handlers-for-widgets"><i class="fa fa-check"></i><b>18.2</b> Input Handlers for Widgets</a></li>
<li class="chapter" data-level="18.3" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#r-to-widgets"><i class="fa fa-check"></i><b>18.3</b> R to Widgets</a>
<ul>
<li class="chapter" data-level="18.3.1" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#send-data-from-widgets"><i class="fa fa-check"></i><b>18.3.1</b> Send Data from Widgets</a></li>
<li class="chapter" data-level="18.3.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#retrieve-widget-instance"><i class="fa fa-check"></i><b>18.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="18.3.3" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#handle-data"><i class="fa fa-check"></i><b>18.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="18.4" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#proxy-function"><i class="fa fa-check"></i><b>18.4</b> Proxy Function</a></li>
<li class="chapter" data-level="18.5" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#clear-data"><i class="fa fa-check"></i><b>18.5</b> Clear Data</a></li>
<li class="chapter" data-level="18.6" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#update-the-widget"><i class="fa fa-check"></i><b>18.6</b> Update the Widget</a></li>
</ul></li>
<li class="part"><span><b>IV Interactive Documents</b></span></li>
<li class="chapter" data-level="19" data-path="introduction-to-rmarkdown.html"><a href="introduction-to-rmarkdown.html"><i class="fa fa-check"></i><b>19</b> Introduction to Rmarkdown</a></li>
<li class="part"><span><b>V JavaScript for Computations</b></span></li>
<li class="chapter" data-level="20" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>20</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="20.1" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i><b>20.1</b> Installation</a></li>
<li class="chapter" data-level="20.2" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i><b>20.2</b> Basics</a></li>
<li class="chapter" data-level="20.3" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i><b>20.3</b> External Libraries</a></li>
<li class="chapter" data-level="20.4" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i><b>20.4</b> With Npm</a></li>
<li class="chapter" data-level="20.5" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i><b>20.5</b> Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html"><i class="fa fa-check"></i><b>21</b> Exercise - Machine Learning</a>
<ul>
<li class="chapter" data-level="21.1" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html#dependency"><i class="fa fa-check"></i><b>21.1</b> Dependency</a></li>
<li class="chapter" data-level="21.2" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html#simple-regression"><i class="fa fa-check"></i><b>21.2</b> Simple Regression</a></li>
</ul></li>
<li class="part"><span><b>VI Examples</b></span></li>
<li class="chapter" data-level="22" data-path="image-classifier.html"><a href="image-classifier.html"><i class="fa fa-check"></i><b>22</b> Image Classifier</a>
<ul>
<li class="chapter" data-level="22.1" data-path="image-classifier.html"><a href="image-classifier.html#discover"><i class="fa fa-check"></i><b>22.1</b> Discover</a></li>
<li class="chapter" data-level="22.2" data-path="image-classifier.html"><a href="image-classifier.html#setup"><i class="fa fa-check"></i><b>22.2</b> Setup</a></li>
<li class="chapter" data-level="22.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>22.3</b> JavaScript</a></li>
<li class="chapter" data-level="22.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>22.4</b> Input Handler</a></li>
</ul></li>
<li class="chapter" data-level="23" data-path="progress-bar.html"><a href="progress-bar.html"><i class="fa fa-check"></i><b>23</b> Progress Bar</a>
<ul>
<li class="chapter" data-level="23.1" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>23.1</b> R code</a></li>
<li class="chapter" data-level="23.2" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>23.2</b> JavaScript code</a></li>
<li class="chapter" data-level="23.3" data-path="progress-bar.html"><a href="progress-bar.html#events"><i class="fa fa-check"></i><b>23.3</b> Events</a></li>
</ul></li>
<li class="part"><span><b>VII Closing Remarks</b></span></li>
<li class="chapter" data-level="24" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>24</b> Conclusion</a>
<ul>
<li class="chapter" data-level="24.1" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>24.1</b> Performances</a></li>
<li class="chapter" data-level="24.2" data-path="conclusion.html"><a href="conclusion.html#road-ahead"><i class="fa fa-check"></i><b>24.2</b> Road ahead</a>
<ul>
<li class="chapter" data-level="24.2.1" data-path="conclusion.html"><a href="conclusion.html#computation"><i class="fa fa-check"></i><b>24.2.1</b> Computation</a></li>
<li class="chapter" data-level="24.2.2" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>24.2.2</b> Shiny</a></li>
<li class="chapter" data-level="24.2.3" data-path="overview.html"><a href="overview.html#htmlwidgets"><i class="fa fa-check"></i><b>24.2.3</b> htmlwidgets</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="tips-tricks" class="section level1" number="14">
<h1><span class="header-section-number">Chapter 14</span> Tips &amp; Tricks</h1>
<p>While previous chapters on working with Shiny made use of external libraries and built packages that brought new functionalities previously not available in shiny, one does not have to go to this length to take advantage of the learnings contained in those pages. Moreover there are a few interesting things that have not yet been explored.</p>
<div id="shiny-events" class="section level2" number="14.1">
<h2><span class="header-section-number">14.1</span> Shiny Events</h2>
<p>There is a wee bit of documentation tucked away on the <a href="https://shiny.rstudio.com/articles/js-events.html">shiny website</a> that contains a useful list of events that Shiny fires to notify the developer of interesting things that happen in the application. This includes events that are fired when outputs are being recalculated, when shiny connects, when an element become visible, and more. To demonstrate how to use those events and how handy they can be we will create a notification which appears to indicate that the server is busy running computations. This could be as fancy as ever but for simplicity’s sake we limit the demonstration to showing and hiding a gif.</p>
<p>First, we create the directories and necessary files, and to indicate the server is busy we’ll be using a gif that is rather well-known in the R community. Note that we will be using some CSS, hence the <code>style.css</code> file.</p>
<div class="sourceCode" id="cb295"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb295-1"><a href="tips-tricks.html#cb295-1"></a><span class="kw">dir.create</span>(<span class="st">&quot;www&quot;</span>)</span>
<span id="cb295-2"><a href="tips-tricks.html#cb295-2"></a><span class="kw">file.create</span>(<span class="st">&quot;www/script.js&quot;</span>)</span>
<span id="cb295-3"><a href="tips-tricks.html#cb295-3"></a><span class="kw">file.create</span>(<span class="st">&quot;www/style.css&quot;</span>)</span>
<span id="cb295-4"><a href="tips-tricks.html#cb295-4"></a></span>
<span id="cb295-5"><a href="tips-tricks.html#cb295-5"></a><span class="co"># gif</span></span>
<span id="cb295-6"><a href="tips-tricks.html#cb295-6"></a>gif &lt;-<span class="st"> </span><span class="kw">paste0</span>(</span>
<span id="cb295-7"><a href="tips-tricks.html#cb295-7"></a>  <span class="st">&quot;https://github.com/JohnCoene/javascript-for-r/&quot;</span>,</span>
<span id="cb295-8"><a href="tips-tricks.html#cb295-8"></a>  <span class="st">&quot;raw/master/code/events/www/typing.gif&quot;</span></span>
<span id="cb295-9"><a href="tips-tricks.html#cb295-9"></a>)</span>
<span id="cb295-10"><a href="tips-tricks.html#cb295-10"></a><span class="kw">download.file</span>(gif, <span class="st">&quot;www/typing.gif&quot;</span>)</span></code></pre></div>
<p>Then we create an application that draws and redraws a plot at the click of a button. Note that we give the gif an id as we will need to be able to retrieve this element JavaScript side (to dynamically show and hide it) and an <code>id</code> makes for an ideal selector.</p>
<div class="sourceCode" id="cb296"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb296-1"><a href="tips-tricks.html#cb296-1"></a><span class="co"># app.R</span></span>
<span id="cb296-2"><a href="tips-tricks.html#cb296-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb296-3"><a href="tips-tricks.html#cb296-3"></a></span>
<span id="cb296-4"><a href="tips-tricks.html#cb296-4"></a>shiny<span class="op">::</span><span class="kw">addResourcePath</span>(<span class="st">&quot;www&quot;</span>, <span class="st">&quot;www&quot;</span>)</span>
<span id="cb296-5"><a href="tips-tricks.html#cb296-5"></a></span>
<span id="cb296-6"><a href="tips-tricks.html#cb296-6"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb296-7"><a href="tips-tricks.html#cb296-7"></a>  <span class="co"># import dependencies</span></span>
<span id="cb296-8"><a href="tips-tricks.html#cb296-8"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb296-9"><a href="tips-tricks.html#cb296-9"></a>    tags<span class="op">$</span><span class="kw">link</span>(<span class="dt">href =</span> <span class="st">&quot;www/style.css&quot;</span>, <span class="dt">rel =</span> <span class="st">&quot;stylesheet&quot;</span>),</span>
<span id="cb296-10"><a href="tips-tricks.html#cb296-10"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;www/script.js&quot;</span>)</span>
<span id="cb296-11"><a href="tips-tricks.html#cb296-11"></a>  ),</span>
<span id="cb296-12"><a href="tips-tricks.html#cb296-12"></a>  <span class="co"># gif indicator</span></span>
<span id="cb296-13"><a href="tips-tricks.html#cb296-13"></a>  tags<span class="op">$</span><span class="kw">img</span>(<span class="dt">src =</span> <span class="st">&quot;www/typing.gif&quot;</span>, <span class="dt">id =</span> <span class="st">&quot;loading&quot;</span>)</span>
<span id="cb296-14"><a href="tips-tricks.html#cb296-14"></a>  <span class="kw">plotOutput</span>(<span class="st">&quot;plot&quot;</span>),</span>
<span id="cb296-15"><a href="tips-tricks.html#cb296-15"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;render&quot;</span>, <span class="st">&quot;render&quot;</span>)</span>
<span id="cb296-16"><a href="tips-tricks.html#cb296-16"></a>)</span>
<span id="cb296-17"><a href="tips-tricks.html#cb296-17"></a></span>
<span id="cb296-18"><a href="tips-tricks.html#cb296-18"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session) {</span>
<span id="cb296-19"><a href="tips-tricks.html#cb296-19"></a>  output<span class="op">$</span>plot &lt;-<span class="st"> </span><span class="kw">renderPlot</span>({</span>
<span id="cb296-20"><a href="tips-tricks.html#cb296-20"></a>    input<span class="op">$</span>render <span class="co"># redraw on click</span></span>
<span id="cb296-21"><a href="tips-tricks.html#cb296-21"></a></span>
<span id="cb296-22"><a href="tips-tricks.html#cb296-22"></a>    <span class="co"># simulate time consuming computations</span></span>
<span id="cb296-23"><a href="tips-tricks.html#cb296-23"></a>    <span class="kw">Sys.sleep</span>(<span class="dv">2</span>) </span>
<span id="cb296-24"><a href="tips-tricks.html#cb296-24"></a>    <span class="kw">plot</span>(cars)</span>
<span id="cb296-25"><a href="tips-tricks.html#cb296-25"></a>  })</span>
<span id="cb296-26"><a href="tips-tricks.html#cb296-26"></a>}</span>
<span id="cb296-27"><a href="tips-tricks.html#cb296-27"></a></span>
<span id="cb296-28"><a href="tips-tricks.html#cb296-28"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>The gif should only be visible when the server is busy, unlike now. Whether it is visible will be controlled in JavaScript so this should be initialised as hidden using CSS. The code below hides the gif with <code>visibility: hidden</code>, and repositions it, floating on top of the rest of the content in the top right of the page, the <code>z-index</code> ensures the gif appears on top of other elements.</p>
<div class="sourceCode" id="cb297"><pre class="sourceCode css"><code class="sourceCode css"><span id="cb297-1"><a href="tips-tricks.html#cb297-1"></a><span class="co">/* style.css */</span></span>
<span id="cb297-2"><a href="tips-tricks.html#cb297-2"></a><span class="pp">#loading</span>{</span>
<span id="cb297-3"><a href="tips-tricks.html#cb297-3"></a>  <span class="kw">top</span>: <span class="dv">20</span><span class="dt">px</span><span class="op">;</span></span>
<span id="cb297-4"><a href="tips-tricks.html#cb297-4"></a>  <span class="kw">right</span>: <span class="dv">20</span><span class="dt">px</span><span class="op">;</span></span>
<span id="cb297-5"><a href="tips-tricks.html#cb297-5"></a>  <span class="kw">height</span>: <span class="dv">200</span><span class="dt">px</span><span class="op">;</span></span>
<span id="cb297-6"><a href="tips-tricks.html#cb297-6"></a>  <span class="kw">z-index</span>: <span class="dv">9999</span><span class="op">;</span></span>
<span id="cb297-7"><a href="tips-tricks.html#cb297-7"></a>  <span class="kw">position</span>: <span class="dv">absolute</span><span class="op">;</span></span>
<span id="cb297-8"><a href="tips-tricks.html#cb297-8"></a>  <span class="kw">visibility</span>: <span class="dv">hidden</span><span class="op">;</span></span>
<span id="cb297-9"><a href="tips-tricks.html#cb297-9"></a>}</span></code></pre></div>
<p>We can then use the shiny events to dynamically show and hide the gif when the server is busy. Below we observe the event <code>shiny:busy</code> on the entire page (<code>document</code>), when the event is triggered the gif is retrieved using its <code>id</code> and then made visible by changing its CSS <code>visibility</code> property to <code>visible</code>.</p>
<div class="sourceCode" id="cb298"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb298-1"><a href="tips-tricks.html#cb298-1"></a><span class="co">// script.js</span></span>
<span id="cb298-2"><a href="tips-tricks.html#cb298-2"></a>$(<span class="bu">document</span>)<span class="op">.</span><span class="fu">on</span>(<span class="st">&#39;shiny:busy&#39;</span><span class="op">,</span> <span class="kw">function</span>(<span class="bu">event</span>) {</span>
<span id="cb298-3"><a href="tips-tricks.html#cb298-3"></a>  <span class="co">// retrieve the gif</span></span>
<span id="cb298-4"><a href="tips-tricks.html#cb298-4"></a>  <span class="kw">var</span> title <span class="op">=</span> <span class="bu">document</span><span class="op">.</span><span class="fu">getElementById</span>(<span class="st">&quot;loading&quot;</span>)<span class="op">;</span></span>
<span id="cb298-5"><a href="tips-tricks.html#cb298-5"></a></span>
<span id="cb298-6"><a href="tips-tricks.html#cb298-6"></a>  <span class="co">// make it visible</span></span>
<span id="cb298-7"><a href="tips-tricks.html#cb298-7"></a>  title<span class="op">.</span><span class="at">style</span><span class="op">.</span><span class="at">visibility</span> <span class="op">=</span> <span class="st">&quot;visible&quot;</span><span class="op">;</span></span>
<span id="cb298-8"><a href="tips-tricks.html#cb298-8"></a>})<span class="op">;</span></span></code></pre></div>
<p>We then need to hide the gif when the server goes from busy to idle, using the <code>shiny:idle</code> event we can change the visibility of the gif back to <code>hidden</code>.</p>
<div class="sourceCode" id="cb299"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb299-1"><a href="tips-tricks.html#cb299-1"></a><span class="co">// script.js</span></span>
<span id="cb299-2"><a href="tips-tricks.html#cb299-2"></a>$(<span class="bu">document</span>)<span class="op">.</span><span class="fu">on</span>(<span class="st">&#39;shiny:busy&#39;</span><span class="op">,</span> <span class="kw">function</span>(<span class="bu">event</span>) {</span>
<span id="cb299-3"><a href="tips-tricks.html#cb299-3"></a>  <span class="co">// retrieve the gif</span></span>
<span id="cb299-4"><a href="tips-tricks.html#cb299-4"></a>  <span class="kw">var</span> gif <span class="op">=</span> <span class="bu">document</span><span class="op">.</span><span class="fu">getElementById</span>(<span class="st">&quot;loading&quot;</span>)<span class="op">;</span></span>
<span id="cb299-5"><a href="tips-tricks.html#cb299-5"></a></span>
<span id="cb299-6"><a href="tips-tricks.html#cb299-6"></a>  <span class="co">// make gif visible</span></span>
<span id="cb299-7"><a href="tips-tricks.html#cb299-7"></a>  gif<span class="op">.</span><span class="at">style</span><span class="op">.</span><span class="at">visibility</span> <span class="op">=</span> <span class="st">&quot;visible&quot;</span><span class="op">;</span></span>
<span id="cb299-8"><a href="tips-tricks.html#cb299-8"></a>})<span class="op">;</span></span>
<span id="cb299-9"><a href="tips-tricks.html#cb299-9"></a></span>
<span id="cb299-10"><a href="tips-tricks.html#cb299-10"></a>$(<span class="bu">document</span>)<span class="op">.</span><span class="fu">on</span>(<span class="st">&#39;shiny:idle&#39;</span><span class="op">,</span> <span class="kw">function</span>(<span class="bu">event</span>) {</span>
<span id="cb299-11"><a href="tips-tricks.html#cb299-11"></a>  <span class="kw">var</span> gif <span class="op">=</span> <span class="bu">document</span><span class="op">.</span><span class="fu">getElementById</span>(<span class="st">&quot;loading&quot;</span>)<span class="op">;</span></span>
<span id="cb299-12"><a href="tips-tricks.html#cb299-12"></a></span>
<span id="cb299-13"><a href="tips-tricks.html#cb299-13"></a>  <span class="co">// hide gif</span></span>
<span id="cb299-14"><a href="tips-tricks.html#cb299-14"></a>  gif<span class="op">.</span><span class="at">style</span><span class="op">.</span><span class="at">visibility</span> <span class="op">=</span> <span class="st">&quot;hidden&quot;</span><span class="op">;</span></span>
<span id="cb299-15"><a href="tips-tricks.html#cb299-15"></a>})<span class="op">;</span></span></code></pre></div>
<p>The application will then display the gif when the server is busy running computations.</p>
<div class="figure">
<img src="images/shiny-events.png" alt="" />
<p class="caption">Shiny with a busy indicator</p>
</div>
</div>
<div id="table-buttons" class="section level2" number="14.2">
<h2><span class="header-section-number">14.2</span> Table Buttons</h2>
<p>For instance, using what was learned previously one can place buttons inside a shiny table and observe server-side which is clicked. Starting with a basic application that only includes a table to which we ultimately want to add a column containing a button on each row. Here we achieve this by having each button set a different value (e.g.: an id) to an input using <code>shiny.setInputValue</code> but one could very well create different input names for each button.</p>
<div class="sourceCode" id="cb300"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb300-1"><a href="tips-tricks.html#cb300-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb300-2"><a href="tips-tricks.html#cb300-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb300-3"><a href="tips-tricks.html#cb300-3"></a></span>
<span id="cb300-4"><a href="tips-tricks.html#cb300-4"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb300-5"><a href="tips-tricks.html#cb300-5"></a>  <span class="kw">DTOutput</span>(<span class="st">&quot;table&quot;</span>)</span>
<span id="cb300-6"><a href="tips-tricks.html#cb300-6"></a>)</span>
<span id="cb300-7"><a href="tips-tricks.html#cb300-7"></a></span>
<span id="cb300-8"><a href="tips-tricks.html#cb300-8"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output) {</span>
<span id="cb300-9"><a href="tips-tricks.html#cb300-9"></a></span>
<span id="cb300-10"><a href="tips-tricks.html#cb300-10"></a>  output<span class="op">$</span>table &lt;-<span class="st"> </span><span class="kw">renderDT</span>({</span>
<span id="cb300-11"><a href="tips-tricks.html#cb300-11"></a>    <span class="kw">datatable</span>(</span>
<span id="cb300-12"><a href="tips-tricks.html#cb300-12"></a>      mtcars, </span>
<span id="cb300-13"><a href="tips-tricks.html#cb300-13"></a>      <span class="dt">escape =</span> <span class="ot">FALSE</span>, </span>
<span id="cb300-14"><a href="tips-tricks.html#cb300-14"></a>      <span class="dt">selection =</span> <span class="st">&quot;none&quot;</span>, </span>
<span id="cb300-15"><a href="tips-tricks.html#cb300-15"></a>      <span class="dt">rownames =</span> <span class="ot">FALSE</span>, </span>
<span id="cb300-16"><a href="tips-tricks.html#cb300-16"></a>      <span class="dt">style =</span> <span class="st">&quot;bootstrap&quot;</span></span>
<span id="cb300-17"><a href="tips-tricks.html#cb300-17"></a>    )</span>
<span id="cb300-18"><a href="tips-tricks.html#cb300-18"></a>  })</span>
<span id="cb300-19"><a href="tips-tricks.html#cb300-19"></a></span>
<span id="cb300-20"><a href="tips-tricks.html#cb300-20"></a>}</span>
<span id="cb300-21"><a href="tips-tricks.html#cb300-21"></a></span>
<span id="cb300-22"><a href="tips-tricks.html#cb300-22"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>Note that in the above we pass some parameters to <code>datatable</code> not all are necessary at the exception of <code>escape</code> which is set to <code>FALSE</code> as we will ultimately place HTML code the table which should appear rendered rather than show said code as a string.</p>
<p>We start by creating the on-click functions as R character strings for each row of the <code>mtcars</code> dataset. This is the function that will be triggered when buttons are clicked. This should look familiar, we use <code>Shiny.setInputValue</code> to define an input named <code>click</code> which is set to a different value for every row of the table.</p>
<div class="sourceCode" id="cb301"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb301-1"><a href="tips-tricks.html#cb301-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb301-2"><a href="tips-tricks.html#cb301-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb301-3"><a href="tips-tricks.html#cb301-3"></a></span>
<span id="cb301-4"><a href="tips-tricks.html#cb301-4"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb301-5"><a href="tips-tricks.html#cb301-5"></a>  <span class="kw">DTOutput</span>(<span class="st">&quot;table&quot;</span>)</span>
<span id="cb301-6"><a href="tips-tricks.html#cb301-6"></a>)</span>
<span id="cb301-7"><a href="tips-tricks.html#cb301-7"></a></span>
<span id="cb301-8"><a href="tips-tricks.html#cb301-8"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output) {</span>
<span id="cb301-9"><a href="tips-tricks.html#cb301-9"></a></span>
<span id="cb301-10"><a href="tips-tricks.html#cb301-10"></a>  output<span class="op">$</span>table &lt;-<span class="st"> </span><span class="kw">renderDT</span>({</span>
<span id="cb301-11"><a href="tips-tricks.html#cb301-11"></a>    <span class="co"># on click function</span></span>
<span id="cb301-12"><a href="tips-tricks.html#cb301-12"></a>    onclick &lt;-<span class="st"> </span><span class="kw">sprintf</span>(</span>
<span id="cb301-13"><a href="tips-tricks.html#cb301-13"></a>      <span class="st">&quot;Shiny.setInputValue(&#39;click&#39;, &#39;%s&#39;)&quot;</span>, </span>
<span id="cb301-14"><a href="tips-tricks.html#cb301-14"></a>      <span class="kw">rownames</span>(mtcars)</span>
<span id="cb301-15"><a href="tips-tricks.html#cb301-15"></a>    ) </span>
<span id="cb301-16"><a href="tips-tricks.html#cb301-16"></a>    </span>
<span id="cb301-17"><a href="tips-tricks.html#cb301-17"></a>    <span class="kw">datatable</span>(</span>
<span id="cb301-18"><a href="tips-tricks.html#cb301-18"></a>      mtcars, </span>
<span id="cb301-19"><a href="tips-tricks.html#cb301-19"></a>      <span class="dt">escape =</span> <span class="ot">FALSE</span>, </span>
<span id="cb301-20"><a href="tips-tricks.html#cb301-20"></a>      <span class="dt">selection =</span> <span class="st">&quot;none&quot;</span>, </span>
<span id="cb301-21"><a href="tips-tricks.html#cb301-21"></a>      <span class="dt">rownames =</span> <span class="ot">FALSE</span>, </span>
<span id="cb301-22"><a href="tips-tricks.html#cb301-22"></a>      <span class="dt">style =</span> <span class="st">&quot;bootstrap&quot;</span></span>
<span id="cb301-23"><a href="tips-tricks.html#cb301-23"></a>    )</span>
<span id="cb301-24"><a href="tips-tricks.html#cb301-24"></a>  })</span>
<span id="cb301-25"><a href="tips-tricks.html#cb301-25"></a></span>
<span id="cb301-26"><a href="tips-tricks.html#cb301-26"></a>}</span>
<span id="cb301-27"><a href="tips-tricks.html#cb301-27"></a></span>
<span id="cb301-28"><a href="tips-tricks.html#cb301-28"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>Next we create the buttons for each row and set the JavaScript functions previously created as the <code>onClick</code> attributes. The JavaScript code passed to the <code>onClick</code> attribute will be executed every time the button is clicked.</p>
<div class="sourceCode" id="cb302"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb302-1"><a href="tips-tricks.html#cb302-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb302-2"><a href="tips-tricks.html#cb302-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb302-3"><a href="tips-tricks.html#cb302-3"></a></span>
<span id="cb302-4"><a href="tips-tricks.html#cb302-4"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb302-5"><a href="tips-tricks.html#cb302-5"></a>  <span class="kw">DTOutput</span>(<span class="st">&quot;table&quot;</span>)</span>
<span id="cb302-6"><a href="tips-tricks.html#cb302-6"></a>)</span>
<span id="cb302-7"><a href="tips-tricks.html#cb302-7"></a></span>
<span id="cb302-8"><a href="tips-tricks.html#cb302-8"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output) {</span>
<span id="cb302-9"><a href="tips-tricks.html#cb302-9"></a></span>
<span id="cb302-10"><a href="tips-tricks.html#cb302-10"></a>  output<span class="op">$</span>table &lt;-<span class="st"> </span><span class="kw">renderDT</span>({</span>
<span id="cb302-11"><a href="tips-tricks.html#cb302-11"></a>    <span class="co"># on click function</span></span>
<span id="cb302-12"><a href="tips-tricks.html#cb302-12"></a>    onclick &lt;-<span class="st"> </span><span class="kw">sprintf</span>(</span>
<span id="cb302-13"><a href="tips-tricks.html#cb302-13"></a>      <span class="st">&quot;Shiny.setInputValue(&#39;click&#39;, &#39;%s&#39;)&quot;</span>, </span>
<span id="cb302-14"><a href="tips-tricks.html#cb302-14"></a>      <span class="kw">rownames</span>(mtcars)</span>
<span id="cb302-15"><a href="tips-tricks.html#cb302-15"></a>    ) </span>
<span id="cb302-16"><a href="tips-tricks.html#cb302-16"></a></span>
<span id="cb302-17"><a href="tips-tricks.html#cb302-17"></a>    <span class="co"># button with onClick function</span></span>
<span id="cb302-18"><a href="tips-tricks.html#cb302-18"></a>    button &lt;-<span class="st"> </span><span class="kw">sprintf</span>(</span>
<span id="cb302-19"><a href="tips-tricks.html#cb302-19"></a>      <span class="st">&quot;&lt;a class=&#39;btn btn-primary&#39; onClick=&#39;%s&#39;&gt;Click me&lt;/a&gt;&quot;</span>,</span>
<span id="cb302-20"><a href="tips-tricks.html#cb302-20"></a>      onclick</span>
<span id="cb302-21"><a href="tips-tricks.html#cb302-21"></a>    )</span>
<span id="cb302-22"><a href="tips-tricks.html#cb302-22"></a></span>
<span id="cb302-23"><a href="tips-tricks.html#cb302-23"></a>    mtcars<span class="op">$</span>button &lt;-<span class="st"> </span>button</span>
<span id="cb302-24"><a href="tips-tricks.html#cb302-24"></a>    <span class="kw">datatable</span>(</span>
<span id="cb302-25"><a href="tips-tricks.html#cb302-25"></a>      mtcars, </span>
<span id="cb302-26"><a href="tips-tricks.html#cb302-26"></a>      <span class="dt">escape =</span> <span class="ot">FALSE</span>, </span>
<span id="cb302-27"><a href="tips-tricks.html#cb302-27"></a>      <span class="dt">selection =</span> <span class="st">&quot;none&quot;</span>, </span>
<span id="cb302-28"><a href="tips-tricks.html#cb302-28"></a>      <span class="dt">rownames =</span> <span class="ot">FALSE</span>, </span>
<span id="cb302-29"><a href="tips-tricks.html#cb302-29"></a>      <span class="dt">style =</span> <span class="st">&quot;bootstrap&quot;</span></span>
<span id="cb302-30"><a href="tips-tricks.html#cb302-30"></a>    )</span>
<span id="cb302-31"><a href="tips-tricks.html#cb302-31"></a>  })</span>
<span id="cb302-32"><a href="tips-tricks.html#cb302-32"></a></span>
<span id="cb302-33"><a href="tips-tricks.html#cb302-33"></a>}</span>
<span id="cb302-34"><a href="tips-tricks.html#cb302-34"></a></span>
<span id="cb302-35"><a href="tips-tricks.html#cb302-35"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>We can then observe the <code>click</code> input and, to demonstrate, render it’s value in the UI.</p>
<div class="sourceCode" id="cb303"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb303-1"><a href="tips-tricks.html#cb303-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb303-2"><a href="tips-tricks.html#cb303-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb303-3"><a href="tips-tricks.html#cb303-3"></a></span>
<span id="cb303-4"><a href="tips-tricks.html#cb303-4"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb303-5"><a href="tips-tricks.html#cb303-5"></a>  <span class="kw">br</span>(),</span>
<span id="cb303-6"><a href="tips-tricks.html#cb303-6"></a>  <span class="kw">DTOutput</span>(<span class="st">&quot;table&quot;</span>),</span>
<span id="cb303-7"><a href="tips-tricks.html#cb303-7"></a>  <span class="kw">strong</span>(<span class="st">&quot;Clicked Model:&quot;</span>),</span>
<span id="cb303-8"><a href="tips-tricks.html#cb303-8"></a>  <span class="kw">verbatimTextOutput</span>(<span class="st">&quot;model&quot;</span>)</span>
<span id="cb303-9"><a href="tips-tricks.html#cb303-9"></a>)</span>
<span id="cb303-10"><a href="tips-tricks.html#cb303-10"></a></span>
<span id="cb303-11"><a href="tips-tricks.html#cb303-11"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output) {</span>
<span id="cb303-12"><a href="tips-tricks.html#cb303-12"></a></span>
<span id="cb303-13"><a href="tips-tricks.html#cb303-13"></a>  output<span class="op">$</span>table &lt;-<span class="st"> </span><span class="kw">renderDT</span>({</span>
<span id="cb303-14"><a href="tips-tricks.html#cb303-14"></a>    <span class="co"># on click function</span></span>
<span id="cb303-15"><a href="tips-tricks.html#cb303-15"></a>    onclick &lt;-<span class="st"> </span><span class="kw">sprintf</span>(</span>
<span id="cb303-16"><a href="tips-tricks.html#cb303-16"></a>      <span class="st">&quot;Shiny.setInputValue(&#39;click&#39;, &#39;%s&#39;)&quot;</span>, </span>
<span id="cb303-17"><a href="tips-tricks.html#cb303-17"></a>      <span class="kw">rownames</span>(mtcars)</span>
<span id="cb303-18"><a href="tips-tricks.html#cb303-18"></a>    ) </span>
<span id="cb303-19"><a href="tips-tricks.html#cb303-19"></a></span>
<span id="cb303-20"><a href="tips-tricks.html#cb303-20"></a>    <span class="co"># button with onClick function</span></span>
<span id="cb303-21"><a href="tips-tricks.html#cb303-21"></a>    button &lt;-<span class="st"> </span><span class="kw">sprintf</span>(</span>
<span id="cb303-22"><a href="tips-tricks.html#cb303-22"></a>      <span class="st">&quot;&lt;a class=&#39;btn btn-primary&#39; onClick=&#39;%s&#39;&gt;Click me&lt;/a&gt;&quot;</span>,</span>
<span id="cb303-23"><a href="tips-tricks.html#cb303-23"></a>      onclick</span>
<span id="cb303-24"><a href="tips-tricks.html#cb303-24"></a>    )</span>
<span id="cb303-25"><a href="tips-tricks.html#cb303-25"></a></span>
<span id="cb303-26"><a href="tips-tricks.html#cb303-26"></a>    <span class="co"># add button to data.frame</span></span>
<span id="cb303-27"><a href="tips-tricks.html#cb303-27"></a>    mtcars<span class="op">$</span>button &lt;-<span class="st"> </span>button</span>
<span id="cb303-28"><a href="tips-tricks.html#cb303-28"></a></span>
<span id="cb303-29"><a href="tips-tricks.html#cb303-29"></a>    <span class="kw">datatable</span>(</span>
<span id="cb303-30"><a href="tips-tricks.html#cb303-30"></a>      mtcars, </span>
<span id="cb303-31"><a href="tips-tricks.html#cb303-31"></a>      <span class="dt">escape =</span> <span class="ot">FALSE</span>, </span>
<span id="cb303-32"><a href="tips-tricks.html#cb303-32"></a>      <span class="dt">selection =</span> <span class="st">&quot;none&quot;</span>, </span>
<span id="cb303-33"><a href="tips-tricks.html#cb303-33"></a>      <span class="dt">rownames =</span> <span class="ot">FALSE</span>, </span>
<span id="cb303-34"><a href="tips-tricks.html#cb303-34"></a>      <span class="dt">style =</span> <span class="st">&quot;bootstrap&quot;</span></span>
<span id="cb303-35"><a href="tips-tricks.html#cb303-35"></a>    )</span>
<span id="cb303-36"><a href="tips-tricks.html#cb303-36"></a>  })</span>
<span id="cb303-37"><a href="tips-tricks.html#cb303-37"></a></span>
<span id="cb303-38"><a href="tips-tricks.html#cb303-38"></a>  output<span class="op">$</span>model &lt;-<span class="st"> </span><span class="kw">renderPrint</span>({</span>
<span id="cb303-39"><a href="tips-tricks.html#cb303-39"></a>    <span class="kw">print</span>(input<span class="op">$</span>click)</span>
<span id="cb303-40"><a href="tips-tricks.html#cb303-40"></a>  })</span>
<span id="cb303-41"><a href="tips-tricks.html#cb303-41"></a>}</span>
<span id="cb303-42"><a href="tips-tricks.html#cb303-42"></a></span>
<span id="cb303-43"><a href="tips-tricks.html#cb303-43"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/dt-button.png" alt="" />
<p class="caption">DT with custom input</p>
</div>
</div>
<div id="jquery---toggle" class="section level2" number="14.3">
<h2><span class="header-section-number">14.3</span> jQuery - Toggle</h2>
<p>The shiny framework itself makes use and thus imports the <a href="https://jquery.com/">jQuery</a> JavaScript library, a library that provides a convenient API to make a lot of things easier, including animations.</p>
<p>As an example, we could use jQuery’s <code>show</code>, <code>hide</code>, or <code>toggle</code> functions to show or hide an HTML element at the press of a button.</p>
<div class="sourceCode" id="cb304"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb304-1"><a href="tips-tricks.html#cb304-1"></a><span class="co">// example of jQuery animation</span></span>
<span id="cb304-2"><a href="tips-tricks.html#cb304-2"></a>$(<span class="st">&#39;#id&#39;</span>)<span class="op">.</span><span class="fu">toggle</span>()<span class="op">;</span></span></code></pre></div>
<p>Because jQuery is already imported there is no need to do so, on the contrary, importing it again will impact load time and might clash with the pre-existing version. Below we create a shiny application containing a message handler to toggle (show or hide element depending on its state) at the click of a button.</p>
<div class="sourceCode" id="cb305"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb305-1"><a href="tips-tricks.html#cb305-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb305-2"><a href="tips-tricks.html#cb305-2"></a></span>
<span id="cb305-3"><a href="tips-tricks.html#cb305-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb305-4"><a href="tips-tricks.html#cb305-4"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb305-5"><a href="tips-tricks.html#cb305-5"></a>    tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb305-6"><a href="tips-tricks.html#cb305-6"></a>      <span class="st">&quot;Shiny.addCustomMessageHandler(</span></span>
<span id="cb305-7"><a href="tips-tricks.html#cb305-7"></a><span class="st">        &#39;jquery-toggle&#39;, function(id){</span></span>
<span id="cb305-8"><a href="tips-tricks.html#cb305-8"></a><span class="st">          $(&#39;#&#39; + id).toggle(); // id</span></span>
<span id="cb305-9"><a href="tips-tricks.html#cb305-9"></a><span class="st">      });&quot;</span></span>
<span id="cb305-10"><a href="tips-tricks.html#cb305-10"></a>    )</span>
<span id="cb305-11"><a href="tips-tricks.html#cb305-11"></a>  ),</span>
<span id="cb305-12"><a href="tips-tricks.html#cb305-12"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;toggle&quot;</span>, <span class="st">&quot;Toggle text&quot;</span>),</span>
<span id="cb305-13"><a href="tips-tricks.html#cb305-13"></a>  <span class="kw">h1</span>(<span class="st">&quot;This text is shown!&quot;</span>, <span class="dt">id =</span> <span class="st">&quot;text&quot;</span>)</span>
<span id="cb305-14"><a href="tips-tricks.html#cb305-14"></a>)</span>
<span id="cb305-15"><a href="tips-tricks.html#cb305-15"></a></span>
<span id="cb305-16"><a href="tips-tricks.html#cb305-16"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb305-17"><a href="tips-tricks.html#cb305-17"></a></span>
<span id="cb305-18"><a href="tips-tricks.html#cb305-18"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>toggle, {</span>
<span id="cb305-19"><a href="tips-tricks.html#cb305-19"></a>    session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="st">&#39;jquery-toggle&#39;</span>, <span class="st">&quot;text&quot;</span>)</span>
<span id="cb305-20"><a href="tips-tricks.html#cb305-20"></a>  })</span>
<span id="cb305-21"><a href="tips-tricks.html#cb305-21"></a></span>
<span id="cb305-22"><a href="tips-tricks.html#cb305-22"></a>}</span>
<span id="cb305-23"><a href="tips-tricks.html#cb305-23"></a></span>
<span id="cb305-24"><a href="tips-tricks.html#cb305-24"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>Note that jQuery takes a selector so one could very well use a class to hide and show multiple elements (with said class) at once.</p>
<div class="sourceCode" id="cb306"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb306-1"><a href="tips-tricks.html#cb306-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb306-2"><a href="tips-tricks.html#cb306-2"></a></span>
<span id="cb306-3"><a href="tips-tricks.html#cb306-3"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb306-4"><a href="tips-tricks.html#cb306-4"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb306-5"><a href="tips-tricks.html#cb306-5"></a>    tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb306-6"><a href="tips-tricks.html#cb306-6"></a>      <span class="st">&quot;Shiny.addCustomMessageHandler(</span></span>
<span id="cb306-7"><a href="tips-tricks.html#cb306-7"></a><span class="st">        &#39;jquery-toggle&#39;, function(selector){</span></span>
<span id="cb306-8"><a href="tips-tricks.html#cb306-8"></a><span class="st">          $(selector).toggle();</span></span>
<span id="cb306-9"><a href="tips-tricks.html#cb306-9"></a><span class="st">      });&quot;</span></span>
<span id="cb306-10"><a href="tips-tricks.html#cb306-10"></a>    )</span>
<span id="cb306-11"><a href="tips-tricks.html#cb306-11"></a>  ),</span>
<span id="cb306-12"><a href="tips-tricks.html#cb306-12"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;toggle&quot;</span>, <span class="st">&quot;Toggle text&quot;</span>),</span>
<span id="cb306-13"><a href="tips-tricks.html#cb306-13"></a>  <span class="kw">h1</span>(<span class="st">&quot;This text is shown!&quot;</span>, <span class="dt">class =</span> <span class="st">&quot;to-toggle&quot;</span>),</span>
<span id="cb306-14"><a href="tips-tricks.html#cb306-14"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;btn&quot;</span>, <span class="st">&quot;Another visible button&quot;</span>, <span class="dt">class =</span> <span class="st">&quot;to-toggle&quot;</span>)</span>
<span id="cb306-15"><a href="tips-tricks.html#cb306-15"></a>)</span>
<span id="cb306-16"><a href="tips-tricks.html#cb306-16"></a></span>
<span id="cb306-17"><a href="tips-tricks.html#cb306-17"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb306-18"><a href="tips-tricks.html#cb306-18"></a></span>
<span id="cb306-19"><a href="tips-tricks.html#cb306-19"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>toggle, {</span>
<span id="cb306-20"><a href="tips-tricks.html#cb306-20"></a>    session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="st">&#39;jquery-toggle&#39;</span>, <span class="st">&quot;.to-toggle&quot;</span>)</span>
<span id="cb306-21"><a href="tips-tricks.html#cb306-21"></a>  })</span>
<span id="cb306-22"><a href="tips-tricks.html#cb306-22"></a></span>
<span id="cb306-23"><a href="tips-tricks.html#cb306-23"></a>}</span>
<span id="cb306-24"><a href="tips-tricks.html#cb306-24"></a></span>
<span id="cb306-25"><a href="tips-tricks.html#cb306-25"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>This is something where, again, R is leveraged in order to make it easier on the shiny developer but it must be said that it suffers from some inefficiency: the message travels from the browser (button click) to the R server where it is sent back to the browser and triggers <code>toggle</code>. It could indeed very well be rewritten in JavaScript entirely, this is however outside the scope of this book.</p>

</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="a-complete-integration.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="custom-outputs.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/4-13-shiny-tips.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
